//
// Created by hjie on 23-9-24.
//

#include <cstdint>
#include <cstring>
#include <string>
#include <unistd.h>
#include <map>
#include <vector>
#include <errno.h>
#include <arpa/inet.h>
#include "loop_event_define.h"
#include "message_attr.h"
#include "stun_message.h"

class StunServerManager;

class StunUdpServer
{
public:
    StunUdpServer(LoopEvent * loop_event, StunServerManager * server_manager);
    ~StunUdpServer();
    void SetPublicIp(const std::string & ip);
    bool CreateUdpServer();
    bool AddSubscriber(AttrXorMappedAddress * address);
    void OnMessage(UdpPacket *packet);
    void SendDataSubscriber(AttrXorMappedAddress * address, uint8_t * data, int length);
    void SendDataSubscriber(uint8_t * data, int length, const std::string & subscriber_key);
    void BroadcastDataToSubscriber(uint8_t * data, int length);
    void SetAllocator(AttrXorMappedAddress * address);
    void UpdateAllocatorInfo(AttrXorMappedAddress * address);
private:
    void ProcessStunMessage(UdpBufferPacket &packet, StunMessage &message);
public:
    LoopEvent * m_loop_event;
    std::shared_ptr<UdpServer> m_udp_server;
    StunServerManager * m_server_manager;
public:
    std::string m_public_ip;
    struct sockaddr_in m_server_sai;
    struct sockaddr_in m_allocator_sai;                        // allocator request informaton
    std::map<std::string,struct sockaddr_in> m_subscriber_map; // permission subscriber
public:
    uint64_t m_refresh_time;
    std::string m_connection_nonce;
};
